package com.pi.pro.xcmg.am.was.edi.infor.common;


import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pi.common.CodesConstants;
import com.pi.common.utils.StringUtils;
import com.pi.pro.xcmg.am.common.XcmgAmConstants;
import com.pi.pro.xcmg.am.common.vo.act.PalletizeChangeData;
import com.pi.pro.xcmg.am.common.vo.edi.XwmsInventoryLineDto;
import com.pi.pro.xcmg.am.was.edi.infor.dto.reply.*;
import com.pi.pro.xcmg.am.was.edi.infor.dto.req.StorageQueryData;
import com.pi.pro.xcmg.am.was.edi.infor.dto.req.StorageQueryObjectDto;
import com.pi.pro.xcmg.am.was.edi.infor.dto.req.TaskOrderDto;
import com.pi.wms.entity.TwtActPalletizeList;
import org.apache.commons.collections.map.HashedMap;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


public class InforWasExchangeSupport {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static StorageQueryData newQuery(String warehouseCode, String materialCode, String locationCode){
        StorageQueryData queryData = new StorageQueryData();
        StorageQueryObjectDto queryObject = new StorageQueryObjectDto();

        if (StringUtils.isNullOrBlank(warehouseCode)){
            warehouseCode = InforWasXcmgExchangeConstants.INFOR_MAP_WH101_WAREHOUSER_ID;
        }
        queryObject.setWhseid(warehouseCode);

        queryObject.setSku("");
        if (!StringUtils.isNullOrBlank(materialCode)){
            queryObject.setSku(materialCode.trim());
        }
        if (StringUtils.isNullOrBlank(locationCode)){
            locationCode = InforWasXcmgExchangeConstants.INFOR_MAP_WH101_LOCATION_CODE;
        }
        queryObject.setLoc(locationCode);

        if (materialCode.indexOf("||")>=0){
            String[] ss=materialCode.split("\\|\\|");
            if ((ss!=null) && (ss.length>0)){
                if (!StringUtils.isNullOrBlank(ss[0])){
                    materialCode=ss[0].trim();
                    queryObject.setSku(materialCode.trim());
                    if ((ss.length>1) && (!StringUtils.isNullOrBlank(ss[1]))){
                        queryObject.setSuppliercode(ss[1].trim());
                    }
                }
            }
        }

        queryData.setData(queryObject);
        return queryData;
    }

    public static void commonValue(FuncReplyData replyData, String processCode){
        if (replyData==null){
            return;
        }
        if (!StringUtils.isNullOrBlank(processCode)){
            replyData.setProcessCode(processCode.trim());
        }
        replyData.setProjectCode(XcmgAmConstants.CUSTOMER_CODE_XCMG_AM);
        replyData.setStartTime(System.currentTimeMillis());
        replyData.setEndTime(System.currentTimeMillis());
        replyData.setUserId(InforWasXcmgExchangeConstants.WAS_USER_ID);
        replyData.setUserName(InforWasXcmgExchangeConstants.WAS_USER_NAME);
    }

    //分组特征码
    public static String groupKey(StorageLineResultDto lineData){
        return groupKey(lineData, "");
    }

    //分组特征码
    public static String groupKey(StorageLineResultDto lineData, String batchNumber){
        String gno="";
        if (lineData==null){
            return gno;
        }
        gno=StringUtils.ifNullOrBlank(lineData.getStorerkey(), XcmgAmConstants.CUSTOMER_CODE_XCMG_AM)         //货主
                + "/" + lineData.getSku()
                + "/" + StringUtils.ifNullOrBlank(lineData.getLottable03(), CodesConstants.COMMON_WILDCARD)   //供应商代码
                + "/" + StringUtils.ifNullOrBlank(lineData.getLottable01(), CodesConstants.COMMON_WILDCARD);  //WBS

        if (!StringUtils.isNullOrBlank(batchNumber)){
            gno=gno+batchNumber.trim();
        }
        return gno;
    }

    //分组特征码
    public static String groupKey(TwtActPalletizeList palletizeList){
        String gno="";
        if (palletizeList==null){
            return gno;
        }
        gno=StringUtils.ifNullOrBlank("", XcmgAmConstants.CUSTOMER_CODE_XCMG_AM)         //货主
                + "/" + palletizeList.getMaterialCode()
                + "/" + StringUtils.ifNullOrBlank(palletizeList.getLotattr06(), CodesConstants.COMMON_WILDCARD)   //供应商代码
                + "/" + StringUtils.ifNullOrBlank(palletizeList.getLotattr07(), CodesConstants.COMMON_WILDCARD);  //WBS

        return gno;
    }

    public static String groupKey(PalletizeChangeData palletizeData){
        String gno="";
        if (palletizeData==null){
            return gno;
        }

        gno=StringUtils.ifNullOrBlank(palletizeData.getCustomercode(), XcmgAmConstants.CUSTOMER_CODE_XCMG_AM)         //货主
                + "/" + palletizeData.getMaterialcode()
                + "/" + StringUtils.ifNullOrBlank(palletizeData.getLotattr06(), CodesConstants.COMMON_WILDCARD)   //供应商代码
                + "/" + StringUtils.ifNullOrBlank(palletizeData.getLotattr07(), CodesConstants.COMMON_WILDCARD);  //WBS
        return gno;
    }

    //分组特征码:出库任务
    public static String groupKey(TaskOrderDto taskOrder){
        String gno="";
        if (taskOrder==null){
            return gno;
        }
        gno=StringUtils.ifNullOrBlank(taskOrder.getSapCode(), CodesConstants.COMMON_WILDCARD)                        //外部单号
                + "/" + StringUtils.ifNullOrBlank(taskOrder.getOrderCode(), CodesConstants.COMMON_WILDCARD)          //订单号,生产订单号
                + "/" + StringUtils.ifNullOrBlank(taskOrder.getWbsno(), CodesConstants.COMMON_WILDCARD)              //订单WBS
                + "/" + StringUtils.ifNullOrBlank(taskOrder.getFactory(), CodesConstants.COMMON_WILDCARD)            //分厂
                + "/" + StringUtils.ifNullOrBlank(taskOrder.getLineCode(), CodesConstants.COMMON_WILDCARD)           //产线
                + "/" + StringUtils.ifNullOrBlank(taskOrder.getStation(), CodesConstants.COMMON_WILDCARD)            //工位
                + "/" + StringUtils.ifNullOrBlank(taskOrder.getStocktaking(), CodesConstants.COMMON_WILDCARD);       //配盘点

        return gno;
    }

    //分组特征码+XWMS批次
    public static Map<String, BigDecimal> summaryByLotnumber(List<TwtActPalletizeList> palletizes){
        Map<String, BigDecimal> summaries=new HashedMap();
        if ((palletizes==null) || (palletizes.size()==0)){
            return summaries;
        }
        String gno="";
        BigDecimal total=null;
        for (TwtActPalletizeList p:palletizes){
            if (p==null){
                continue;
            }
            if ((p.getQty()==null) || (p.getQty().compareTo(BigDecimal.ZERO)<=0)){
                continue;
            }
            gno=groupKey(p) + "/" + StringUtils.ifNullOrBlank(p.getUdf07(), CodesConstants.COMMON_WILDCARD);   //XWMS批次
            total=summaries.get(gno);
            if (total==null){
                total=BigDecimal.ZERO;
            }
            total=total.add(p.getQty());
            summaries.put(gno, total);
        }
        return summaries;
    }

    //
    public static String checkOrder(List<TaskOrderDto> taskOrders){
        String m = "";
        if ((taskOrders==null) || (taskOrders.size()==0)){
            m="订单数据为空";
            return m;
        }
        Map<String,String> tmaps=new HashedMap();
        for (TaskOrderDto t:taskOrders){
            m=check(t);
            if (!StringUtils.isNullOrBlank(m)){
                return m;
            }
            if (tmaps.containsKey(t.getTaskCode())){
                m="列表中,任务号重复:"+t.getTaskCode();
                return m;
            }
        }
        return m;
    }

    public static String trimOrder(List<TaskOrderDto> taskOrders){
        String m = "";
        if ((taskOrders==null) || (taskOrders.size()==0)){
            return m;
        }
        for (TaskOrderDto t:taskOrders){
            //
            if (!StringUtils.isNullOrBlank(t.getType())){
                t.setType(t.getType().trim());
            }

            if (!StringUtils.isNullOrBlank(t.getOwner())){
                t.setOwner(t.getOwner().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getMCode())){
                t.setMCode(t.getMCode().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getSupplier())){
                t.setSupplier(t.getSupplier().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getWbsno())){
                t.setWbsno(t.getWbsno().trim());
            }

            //
            if (!StringUtils.isNullOrBlank(t.getSapCode())){
                t.setSapCode(t.getSapCode().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getOrderCode())){
                t.setOrderCode(t.getOrderCode().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getErpCode())){
                t.setErpCode(t.getErpCode().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getWbsno())){
                t.setWbsno(t.getWbsno().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getFactory())){
                t.setFactory(t.getFactory().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getLineCode())){
                t.setLineCode(t.getLineCode().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getStocktaking())){
                t.setStocktaking(t.getStocktaking().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getStation())){
                t.setStation(t.getStation().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getTaskCode())){
                t.setTaskCode(t.getTaskCode().trim());
            }

            //
            if (!StringUtils.isNullOrBlank(t.getErpTime())){
                t.setErpTime(t.getErpTime().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getFromLoc())){
                t.setFromLoc(t.getFromLoc().trim());
            }
            if (!StringUtils.isNullOrBlank(t.getToLoc())){
                t.setToLoc(t.getToLoc().trim());
            }
        }
        return m;
    }




    //
    public static String check(TaskOrderDto taskOrder){
        String m = "";
        if (taskOrder==null){
            m="订单数据为空";
            return m;
        }
        if (StringUtils.isNullOrBlank(taskOrder.getMCode())){
            m="无效订单数据.物料码为空.";
            return m;
        }
        if ((taskOrder.getQuantity()==null) || (taskOrder.getQuantity().compareTo(BigDecimal.ZERO))<=0){
            m="无效订单数据.出库数量必须大于0.";
            return m;
        }
        if (StringUtils.isNullOrBlank(taskOrder.getTaskCode())){
            m="无效订单数据.任务号为空.";
            return m;
        }
        if (StringUtils.isNullOrBlank(taskOrder.getType())){
            m="无效订单数据.类型为空.";
            return m;
        }
        return m;
    }


    public static String check(StorageLineResultDto line){
        String m = "";
        if (line==null){
            m="空库存数据";
            return m;
        }
        if (StringUtils.isNullOrBlank(line.getSku())){
            m="无效库存数据.物料编码为空.";
            return m;
        }
        if ((line.getQty()==null) || (line.getQty().compareTo(BigDecimal.ZERO))<=0){
            m="无效库存数据.库存数量必须大于0.";
            return m;
        }
        return m;
    }

    public static String trim(StorageLineResultDto line){
        String m = "";
        if (line==null){
            return m;
        }
        if (!StringUtils.isNullOrBlank(line.getSku())){
            line.setSku(line.getSku().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getStorerkey())){
            line.setStorerkey(line.getStorerkey().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getLottable01())){
            line.setLottable01(line.getLottable01().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getLottable02())){
            line.setLottable02(line.getLottable02().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getLottable03())){
            line.setLottable03(line.getLottable03().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getLottable04())){
            line.setLottable04(line.getLottable04().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getLot())){
            line.setLot(line.getLot().trim());
        }
        if (!StringUtils.isNullOrBlank(line.getLoc())){
            line.setLoc(line.getLoc().trim());
        }
        return m;
    }

    public static <T> FuncReplyData<T> parseJson(String jsonText, Class<T> elementType) throws Exception {

        FuncReplyData<T> replyData = null;
        // 构建完整的泛型类型信息
        if (StringUtils.isNullOrBlank(jsonText)){
            replyData = errorReply("未接收到反馈,请确认调度系统已正常启动");
            return replyData;
        }
        JavaType type = null;
        try{
            type = objectMapper.getTypeFactory().constructParametricType(FuncReplyData.class, elementType);
            replyData = objectMapper.readValue(jsonText, type);
        }catch (Exception e){
            e.printStackTrace();
            replyData = errorReply(e.getMessage());
        }
        return replyData;
    }


    public static <T> FuncReplyData<T> trimParseJson(String jsonText, Class<T> elementType) throws Exception {

        FuncReplyData<T> replyData = null;
        // 构建完整的泛型类型信息
        if (StringUtils.isNullOrBlank(jsonText)){
            replyData = errorReply("未接收到反馈,请确认调度系统已正常启动");
            return replyData;
        }
        JavaType type = null;
        try{
            if (jsonText.startsWith("[")){
                jsonText = jsonText.substring(1,jsonText.length());
            }
            if (jsonText.endsWith("]")){
                jsonText= jsonText.substring(0,jsonText.length()-1);
            }

            type = objectMapper.getTypeFactory().constructParametricType(FuncReplyData.class, elementType);
            replyData = objectMapper.readValue(jsonText, type);
        }catch (Exception e){
            e.printStackTrace();
            replyData = errorReply(e.getMessage());
        }
        return replyData;
    }


    /**
    public static <T> FuncListReplyData<T> parseListJson(String jsonText, Class<T> elementType) throws Exception {

        FuncListReplyData<T> replyData = null;
        // 构建完整的泛型类型信息
        if (StringUtils.isNullOrBlank(jsonText)){
            //replyData = errorReply("未接收到反馈,请确认调度系统已正常启动");
            return replyData;
        }
        JavaType type = null;
        try{

            if (jsonText.startsWith("[")){
                jsonText.substring(1,jsonText.length());
            }
            if (jsonText.endsWith("[")){
                jsonText.substring(1,jsonText.length());
            }

            type = objectMapper.getTypeFactory().constructParametricType(FuncListReplyData.class, elementType);
            replyData = objectMapper.readValue(jsonText, type);
        }catch (Exception e){
            e.printStackTrace();
            //replyData = errorReply(e.getMessage());
        }
        return replyData;
    }
    **/

    public static <T> FuncReplyListData<T> parseListJson(String jsonText, Class<T> elementType) throws Exception {

        FuncReplyListData<T> replyData = null;
        // 构建完整的泛型类型信息
        if (StringUtils.isNullOrBlank(jsonText)){
            replyData = errorReplyList("未接收到反馈,请确认调度系统已正常启动");
            return replyData;
        }
        JavaType type = null;
        try{
            if (jsonText.startsWith("[")){
                jsonText = jsonText.substring(1,jsonText.length());
            }
            if (jsonText.endsWith("]")){
                jsonText= jsonText.substring(0,jsonText.length()-1);
            }

            type = objectMapper.getTypeFactory().constructParametricType(FuncReplyListData.class, elementType);
            replyData = objectMapper.readValue(jsonText, type);
        }catch (Exception e){
            e.printStackTrace();
            replyData = errorReplyList(e.getMessage());
        }
        return replyData;
    }

    // 或直接使用 TypeReference
    public static <T> FuncReplyData<T> parseWithTypeReference(String jsonText) {
        FuncReplyData<T> replyData = null;
        if (StringUtils.isNullOrBlank(jsonText)){
            replyData = errorReply("未接收到反馈,请确认调度系统已正常启动");
            return replyData;
        }
        try{
            replyData=objectMapper.readValue(jsonText, new TypeReference<FuncReplyData<T>>() {});
        }catch (Exception e){
            e.printStackTrace();
            replyData = errorReply(e.getMessage());
        }
        return replyData;
    }

    public static <T> FuncReplyData<T> errorReply(String errorText){
        if (StringUtils.isNullOrBlank(errorText)){
            errorText="System Error.";
        }
        FuncReplyData replyData=new FuncReplyData();
        commonValue(replyData, "");
        replyData.setErrors(Arrays.asList(errorText));
        replyData.setWarnErrors(errorText);
        replyData.setResultData(null);
        return replyData;
    }

    public static <T> FuncReplyListData<T> errorReplyList(String errorText){
        if (StringUtils.isNullOrBlank(errorText)){
            errorText="System Error.";
        }
        FuncReplyListData replyData=new FuncReplyListData();
        //commonValue(replyData, "");
        replyData.setErrors(Arrays.asList(errorText));
        replyData.setWarnErrors(errorText);
        replyData.setResultData(null);
        return replyData;
    }

    public static <T> FuncReplyData<T> emptyReply(){
        FuncReplyData replyData=new FuncReplyData();
        replyData.setErrors(new ArrayList<>());
        commonValue(replyData, "");
        replyData.setWarnErrors(null);
        replyData.setResultData(null);
        return replyData;
    }

    public static FuncReplyData<StorageLineResultDto> emptyStorageResultReply(){
        FuncReplyData replyData=new FuncReplyData();
        commonValue(replyData, InforWasXcmgExchangeConstants.FUNC_CODE_INVENTORY_QUERY);
        replyData.setErrors(new ArrayList<>());
        replyData.setWarnErrors(null);
        replyData.setResultData(null);
        return replyData;
    }

    public static FuncReplyData<TaskReportResultDto> emptyTaskReportResultReply(){
        FuncReplyData replyData=new FuncReplyData();
        commonValue(replyData, InforWasXcmgExchangeConstants.FUNC_CODE_INVENTORY_QUERY);
        replyData.setErrors(new ArrayList<>());
        replyData.setWarnErrors(null);
        replyData.setResultData(null);
        return replyData;
    }

    public static CommonResultData ok(){
        CommonResultData replyData=new CommonResultData();
        replyData.setResultCode(InforWasXcmgExchangeConstants.RESULT_CODE_OK);
        replyData.setMessage("成功");
        return replyData;
    }

    public static CommonResultData error(String errorText){
        CommonResultData replyData=new CommonResultData();
        replyData.setResultCode(InforWasXcmgExchangeConstants.RESULT_CODE_APP_ERROR);
        if (StringUtils.isNullOrBlank(errorText)){
            errorText="发生异常.";
        }
        replyData.setMessage(errorText);
        return replyData;
    }

    public static String taskkeyOf(FuncReplyData<TaskReportResultDto> replyData){
        String key="";
        if ((replyData==null) || (replyData.getResultData()==null) || (replyData.getResultData().getProcessOutputs()==null)){
            return key;
        }
        key = replyData.getResultData().getProcessOutputs().getTaskkey();
        return key;
    }

    public static <T> boolean hasError(FuncReplyData<T> replyData){
        if (replyData==null){
            return true;
        }
        if ((replyData.getErrors()!=null) && (replyData.getErrors().size()>0)){
            for (String e:replyData.getErrors()){
                if (!StringUtils.isNullOrBlank(e)){
                    return true;
                }
            }
            return true;
        }
        //
        if (!StringUtils.isNullOrBlank(replyData.getWarnErrors())){
            return true;
        }
        return false;
    }

    public static <T> String errorMessage(FuncReplyData<T> replyData){
        String m = "";
        if (replyData==null){
            m="未来接收到X-WMS反馈,请确认接口系统正常.";
            return m;
        }
        if ((replyData.getErrors()!=null) && (replyData.getErrors().size()>0)){
            for (String e:replyData.getErrors()){
                if (!StringUtils.isNullOrBlank(e)){
                    m=e;
                    return m;
                }
            }
            m="获取X-WMS数据异常.请联系系统管理员.";
            return m;
        }
        //
        if (!StringUtils.isNullOrBlank(replyData.getWarnErrors())){
            m=replyData.getWarnErrors();
            return m;
        }
        return m;
    }

    public static <T> String errorListMessage(FuncReplyListData<T> replyData){
        String m = "";
        if (replyData==null){
            m="未来接收到X-WMS反馈,请确认接口系统正常.";
            return m;
        }
        if ((replyData.getErrors()!=null) && (replyData.getErrors().size()>0)){
            for (String e:replyData.getErrors()){
                if (!StringUtils.isNullOrBlank(e)){
                    m=e;
                    return m;
                }
            }
            m="获取X-WMS数据异常.请联系系统管理员.";
            return m;
        }
        //
        if (!StringUtils.isNullOrBlank(replyData.getWarnErrors())){
            m=replyData.getWarnErrors();
            return m;
        }
        return m;
    }
}
